#include "event_bus.h"
#include "spdlog/spdlog.h"
#include <stdexcept>

EventBus& EventBus::instance() {
    static EventBus instance;
    return instance;
}

template <typename T>
void EventBus::subscribe(std::shared_ptr<EventHandler<T>> handler) {
    std::unique_lock lock(mutex_);
    auto& handlers = handlers_[typeid(T)];
    handlers.push_back(handler);
}

template <typename T>
void EventBus::unsubscribe(std::shared_ptr<EventHandler<T>> handler) {
    std::unique_lock lock(mutex_);
    auto it = handlers_.find(typeid(T));
    if (it != handlers_.end()) {
        auto& handlers = it->second;
        handlers.erase(std::remove_if(handlers.begin(), handlers.end(),
            [&](const auto& item) {
                auto h = std::static_pointer_cast<EventHandler<T>>(item);
                return h == handler;
            }), handlers.end());
    }
}

template <typename T>
void EventBus::publish(const T& event) {
    std::shared_lock lock(mutex_);
    auto it = handlers_.find(typeid(T));
    if (it != handlers_.end()) {
        for (const auto& handler : it->second) {
            try {
                auto h = std::static_pointer_cast<EventHandler<T>>(handler);
                if (h) {
                    h->handle(event);
                }
            } catch (const std::exception& e) {
                SPDLOG_ERROR("Event handling failed: {}", e.what());
            }
        }
    }
}

void EventBus::clear() {
    std::unique_lock lock(mutex_);
    handlers_.clear();
}

// 显式实例化常用事件类型
template void EventBus::subscribe<OrderEvent>(std::shared_ptr<EventHandler<OrderEvent>>);
template void EventBus::unsubscribe<OrderEvent>(std::shared_ptr<EventHandler<OrderEvent>>);
template void EventBus::publish<OrderEvent>(const OrderEvent&);